#!/usr/bin/env python

import os
import sys
import string
import traceback
import signal
import pytoss
from pytoss.users import UserManager
from pytoss.tasks import TaskManager
from pytoss.tasks import TaskExecutionError
from pytoss.receipts import ReceiptManager
from pytoss.receipts import TextualReceipt
from pytoss.flags import TossflagManager
from pytoss.flags import Tossflag

def indent_description(desc):
    return pytoss.utils.indent_multiline_string(desc, TaskManager.get_instance().len_of_longest_task_name() + 7).strip()

# signal handling
def toss_signal_handler(signum, frame):
    print ""
    pytoss.interaction.StreamMonitorTracker.get_instance().ask_all_monitors_to_force_quit()

signals_to_handle = [
    signal.SIGHUP,
    signal.SIGINT,
    signal.SIGQUIT,
    signal.SIGTRAP,
    signal.SIGABRT,
]

for sig in signals_to_handle:
    signal.signal(sig, toss_signal_handler)

try:
    terminal_cols = int(os.environ['COLUMNS'])
    terminal_cols = min([terminal_cols, 80])
except:
    terminal_rows = 0
    terminal_cols = 0


Tossflag("dry-run").explain("shows the sequence of commands without actually executing them")
if Tossflag("dry-run").given:
    UserManager.get_instance().force_all_users_to_use_dry_run_strategies()


# collect all tasks by importing the local tossfile
pytoss.Tossfile( os.path.abspath( os.getcwd() ) )


# otherwise, consider the first argument to be a Task name
non_flag_args = []
for arg in sys.argv[1:]:
    if not arg.startswith("--"):
        non_flag_args.append(arg)

if len(non_flag_args) >= 1:
    
    # we have a task to execute
    print ">"*terminal_cols
    task_name = non_flag_args[0]
    task = TaskManager.get_instance().find_task(task_name)
    
    # by default, if no receipts were specified then we create
    # a TextualReceipt on stdout
    if len( ReceiptManager.get_instance().receipts ) == 0:
        default_receipt = TextualReceipt(sys.stdout)
        ReceiptManager.get_instance().add_receipt( default_receipt )
    
    if task:
        try:
            try:
                task.execute()
                print "<"*terminal_cols
                print "success!"
            except TaskExecutionError:
                print "<"*terminal_cols
                print "failed, check the receipt for details"
        except:
            print "*** fatal pytoss error"
            backtrace = traceback.format_tb(sys.exc_info()[2])
            print "\n%s: %s" % (sys.exc_info()[0], sys.exc_info()[1])
            print "".join(backtrace)
            sys.exit(1)

        sys.exit(0)
        
    else:
        print "<"*terminal_cols
        print "no task exists by the name '%s'" % task_name
        sys.exit(1)
        
else:
    
    # no task given, show the list of tasks
    print "="*terminal_cols
    
    tasks = TaskManager.get_instance().get_all_tasks()
    
    root_tasks = []
    namespaced_tasks = []
    for task in tasks:
        if task.name.find(".") == -1 and task.name.find(pytoss.utils.os_path_separator) == -1:
            root_tasks.append(task)
        else:
            namespaced_tasks.append(task)
    
    max_len = TaskManager.get_instance().len_of_longest_task_name()
    format_string = "  toss %%-%ss  # %%s" % max_len
    current_namespace = None
    
    for task in root_tasks:
        if task.description:
            desc = task.description
        else:
            desc = ""
        print format_string % (task.name, indent_description(desc))
    
    for task in namespaced_tasks:    
        last_slash_index = task.name.rfind(pytoss.utils.os_path_separator)
        if last_slash_index != -1:
            pre_namespace = task.name[0:last_slash_index]
        else:
            pre_namespace = ""
        if "." in task.name:
            new_namespace = pre_namespace + task.name.split(".")[0]
        else:
            new_namespace = pre_namespace

        if new_namespace != current_namespace:
            # new namespace
            print ""
            current_namespace = new_namespace
        if task.description:
            desc = task.description
        else:
            desc = ""
        print format_string % (task.name, indent_description(desc))
        
    print ""
    explanations = TossflagManager.get_instance().get_all_explanations()
    for tossflag_name in explanations:
        print "  [--%s] %s" % (tossflag_name, explanations[tossflag_name])
    
    print "="*terminal_cols
    sys.exit(0)
    